
<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <title>
    
  back-end - LZH-DEV-TECH-SHARE
  

  </title>
  <meta name="author" content="">
  <meta name="description" content="">

  <meta name="HandheldFriendly" content="True">
  <meta name="MobileOptimized" content="320">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  <link href="asset/css/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
  <link href="atom.xml" rel="alternate" title="LZH-DEV-TECH-SHARE" type="application/atom+xml">
  <script src="asset/js/modernizr-2.0.js"></script>
  <script src="asset/js/jquery.min.js"></script>
  <script src="asset/highlightjs/highlight.pack.js"></script>
  <link href="asset/highlightjs/styles/solarized_light.css" media="screen, projection" rel="stylesheet" type="text/css">
  <script>hljs.initHighlightingOnLoad();</script>

  <style type="text/css">
  .cat-children-p{ padding: 6px 0px;}
  .hljs{background: none;}
  </style>
  <script type="text/javascript">
  var isAddSildbar = true;
  </script>
  <script src="asset/js/octopress.js" type="text/javascript"></script>
</head>
<script type="text/javascript">
//链接新开窗口
function addBlankTargetForLinks () {
  $('a[href^="http"]').each(function(){
      $(this).attr('target', '_blank');
  });
}
$(document).ready(function(event) {
  addBlankTargetForLinks();
});
</script>
<body   >
  <header role="banner"><hgroup>
  <h1><a href="index.html">LZH-DEV-TECH-SHARE</a></h1>
  
    <h2></h2>
  
</hgroup>

</header>
  <nav role="navigation"><ul class="subscription" data-subscription="rss">
  <li><a href="atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
  
</ul>
  
<form action="http://google.com/search" method="get">
  <fieldset role="search">
    <input type="hidden" name="q" value="site:" />
    <input class="search" type="text" name="q" results="0" placeholder="Search"/>
  </fieldset>
</form>
  
<ul class="main-navigation">

  <li id=""><a target="self" href="index.html">Home</a></li>

  <li id=""><a target="_self" href="archives.html">Archives</a></li>

</ul>

</nav>
  <div id="main">
    <div id="content"> 
<div class="blog-index">

	<article>
		 <header>
		  	<h1 class="entry-title"><a href="15413898294420.html">RESTful API 最佳实践</a></h1>
			<p class="meta"><time datetime="2018-11-05T11:50:29+08:00" 
			pubdate data-updated="true">2018/11/5</time></p>
		 </header>
	  	<div class="entry-content">
		  	
		  	<p><a href="http://www.ruanyifeng.com/blog/2011/09/restful.html">RESTful</a> 是目前最流行的 API 设计规范，用于 Web 数据接口的设计。<br/>
它的大原则容易把握，但是细节不容易做对。本文总结 RESTful 的设计细节，介绍如何设计出易于理解和使用的 API。</p>

<h2 id="toc_0">一、URL 设计</h2>

<h3 id="toc_1">1.1 动词 + 宾语</h3>

<p>RESTful 的核心思想就是，客户端发出的数据操作指令都是&quot;动词 + 宾语&quot;的结构。比如，GET /articles这个命令，GET是动词，/articles是宾语。<br/>
动词通常就是五种 HTTP 方法，对应 CRUD 操作。</p>

<pre><code class="language-text">GET：读取（Read）
POST：新建（Create）
PUT：更新（Update）
PATCH：更新（Update），通常是部分更新
DELETE：删除（Delete）
</code></pre>

<p>根据 HTTP 规范，动词一律大写。</p>

<h3 id="toc_2">1.2 动词的覆盖</h3>

<p>有些客户端只能使用GET和POST这两种方法。服务器必须接受POST模拟其他三个方法（PUT、PATCH、DELETE）。<br/>
这时，客户端发出的 HTTP 请求，要加上X-HTTP-Method-Override属性，告诉服务器应该使用哪一个动词，覆盖POST方法。</p>

<pre><code class="language-text">POST /api/Person/4 HTTP/1.1  
X-HTTP-Method-Override: PUT
</code></pre>

<p>上面代码中，X-HTTP-Method-Override指定本次请求的方法是PUT，而不是POST。</p>

<h3 id="toc_3">1.3 宾语必须是名词</h3>

<p>宾语就是 API 的 URL，是 HTTP 动词作用的对象。它应该是名词，不能是动词。比如，/articles这个 URL 就是正确的，而下面的 URL 不是名词，所以都是错误的。</p>

<pre><code class="language-text">/getAllCars
/createNewCar
/deleteAllRedCars
</code></pre>

<h3 id="toc_4">1.4 复数 URL</h3>

<p>既然 URL 是名词，那么应该使用复数，还是单数？<br/>
这没有统一的规定，但是常见的操作是读取一个集合，比如GET /articles（读取所有文章），这里明显应该是复数。<br/>
为了统一起见，建议都使用复数 URL，比如GET /articles/2要好于GET /article/2。</p>

<h3 id="toc_5">1.5 避免多级 URL</h3>

<p>常见的情况是，资源需要多级分类，因此很容易写出多级的 URL，比如获取某个作者的某一类文章。</p>

<pre><code class="language-text">GET /authors/12/categories/2
</code></pre>

<p>这种 URL 不利于扩展，语义也不明确，往往要想一会，才能明白含义。<br/>
更好的做法是，除了第一级，其他级别都用查询字符串表达。</p>

<pre><code class="language-text">GET /authors/12?categories=2
</code></pre>

<p>下面是另一个例子，查询已发布的文章。你可能会设计成下面的 URL。</p>

<pre><code class="language-text">GET /articles/published
</code></pre>

<p>查询字符串的写法明显更好。</p>

<pre><code class="language-text">GET /articles?published=true
</code></pre>

<h2 id="toc_6">二、状态码</h2>

<h3 id="toc_7">2.1 状态码必须精确</h3>

<p>客户端的每一次请求，服务器都必须给出回应。回应包括 HTTP 状态码和数据两部分。<br/>
HTTP 状态码就是一个三位数，分成五个类别。</p>

<pre><code class="language-text">1xx：相关信息
2xx：操作成功
3xx：重定向
4xx：客户端错误
5xx：服务器错误
</code></pre>

<p>这五大类总共包含100多种状态码，覆盖了绝大部分可能遇到的情况。每一种状态码都有标准的（或者约定的）解释，客户端只需查看状态码，就可以判断出发生了什么情况，所以服务器应该返回尽可能精确的状态码。<br/>
API 不需要1xx状态码，下面介绍其他四类状态码的精确含义。</p>

<h3 id="toc_8">2.2 2xx 状态码</h3>

<p>200状态码表示操作成功，但是不同的方法可以返回更精确的状态码。</p>

<pre><code class="language-text">GET: 200 OK
POST: 201 Created
PUT: 200 OK
PATCH: 200 OK
DELETE: 204 No Content
</code></pre>

<p>上面代码中，POST返回201状态码，表示生成了新的资源；DELETE返回204状态码，表示资源已经不存在。<br/>
此外，202 Accepted状态码表示服务器已经收到请求，但还未进行处理，会在未来再处理，通常用于异步操作。下面是一个例子。</p>

<pre><code class="language-javascript">HTTP/1.1 202 Accepted

{
  &quot;task&quot;: {
    &quot;href&quot;: &quot;/api/company/job-management/jobs/2130040&quot;,
    &quot;id&quot;: &quot;2130040&quot;
  }
}
</code></pre>

<h3 id="toc_9">2.3 3xx 状态码</h3>

<p>API 用不到301状态码（永久重定向）和302状态码（暂时重定向，307也是这个含义），因为它们可以由应用级别返回，浏览器会直接跳转，API 级别可以不考虑这两种情况。<br/>
API 用到的3xx状态码，主要是303 See Other，表示参考另一个 URL。它与302和307的含义一样，也是&quot;暂时重定向&quot;，区别在于302和307用于GET请求，而303用于POST、PUT和DELETE请求。收到303以后，浏览器不会自动跳转，而会让用户自己决定下一步怎么办。下面是一个例子。</p>

<pre><code class="language-text">HTTP/1.1 303 See Other
Location: /api/orders/12345
</code></pre>

<h3 id="toc_10">2.4 4xx 状态码</h3>

<p>4xx状态码表示客户端错误，主要有下面几种。<br/>
400 Bad Request：服务器不理解客户端的请求，未做任何处理。<br/>
401 Unauthorized：用户未提供身份验证凭据，或者没有通过身份验证。<br/>
403 Forbidden：用户通过了身份验证，但是不具有访问资源所需的权限。<br/>
404 Not Found：所请求的资源不存在，或不可用。<br/>
405 Method Not Allowed：用户已经通过身份验证，但是所用的 HTTP 方法不在他的权限之内。<br/>
410 Gone：所请求的资源已从这个地址转移，不再可用。<br/>
415 Unsupported Media Type：客户端要求的返回格式不支持。比如，API 只能返回 JSON 格式，但是客户端要求返回 XML 格式。<br/>
422 Unprocessable Entity ：客户端上传的附件无法处理，导致请求失败。<br/>
429 Too Many Requests：客户端的请求次数超过限额。</p>

<h3 id="toc_11">2.5 5xx 状态码</h3>

<p>5xx状态码表示服务端错误。一般来说，API 不会向用户透露服务器的详细信息，所以只要两个状态码就够了。<br/>
500 Internal Server Error：客户端请求有效，服务器处理时发生了意外。<br/>
503 Service Unavailable：服务器无法处理请求，一般用于网站维护状态。</p>

<h2 id="toc_12">三、服务器回应</h2>

<h3 id="toc_13">3.1 不要返回纯本文</h3>

<p>API 返回的数据格式，不应该是纯文本，而应该是一个 JSON 对象，因为这样才能返回标准的结构化数据。所以，服务器回应的 HTTP 头的Content-Type属性要设为application/json。<br/>
客户端请求时，也要明确告诉服务器，可以接受 JSON 格式，即请求的 HTTP 头的ACCEPT属性也要设成application/json。下面是一个例子。</p>

<pre><code class="language-javascript">GET /orders/2 HTTP/1.1 
Accept: application/json
</code></pre>

<h3 id="toc_14">3.2 发生错误时，不要返回 200 状态码</h3>

<p>有一种不恰当的做法是，即使发生错误，也返回200状态码，把错误信息放在数据体里面，就像下面这样。</p>

<pre><code class="language-javascript">HTTP/1.1 200 OK
Content-Type: application/json

{
  &quot;status&quot;: &quot;failure&quot;,
  &quot;data&quot;: {
    &quot;error&quot;: &quot;Expected at least two items in list.&quot;
  }
}
</code></pre>

<p>上面代码中，解析数据体以后，才能得知操作失败。<br/>
这张做法实际上取消了状态码，这是完全不可取的。正确的做法是，状态码反映发生的错误，具体的错误信息放在数据体里面返回。下面是一个例子。</p>

<pre><code class="language-javascript">HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  &quot;error&quot;: &quot;Invalid payoad.&quot;,
  &quot;detail&quot;: {
     &quot;surname&quot;: &quot;This field is required.&quot;
  }
}
</code></pre>

<h3 id="toc_15">3.3 提供链接</h3>

<p>API 的使用者未必知道，URL 是怎么设计的。一个解决方法就是，在回应中，给出相关链接，便于下一步操作。这样的话，用户只要记住一个 URL，就可以发现其他的 URL。这种方法叫做 HATEOAS。<br/>
举例来说，GitHub 的 API 都在 api.github.com 这个域名。访问它，就可以得到其他 URL。</p>

<pre><code class="language-javascript">{
  ...
  &quot;feeds_url&quot;: &quot;https://api.github.com/feeds&quot;,
  &quot;followers_url&quot;: &quot;https://api.github.com/user/followers&quot;,
  &quot;following_url&quot;: &quot;https://api.github.com/user/following{/target}&quot;,
  &quot;gists_url&quot;: &quot;https://api.github.com/gists{/gist_id}&quot;,
  &quot;hub_url&quot;: &quot;https://api.github.com/hub&quot;,
  ...
}
</code></pre>

<p>上面的回应中，挑一个 URL 访问，又可以得到别的 URL。对于用户来说，不需要记住 URL 设计，只要从 api.github.com 一步步查找就可以了。<br/>
HATEOAS 的格式没有统一规定，上面例子中，GitHub 将它们与其他属性放在一起。更好的做法应该是，将相关链接与其他属性分开。</p>

<pre><code class="language-javascript">HTTP/1.1 200 OK
Content-Type: application/json

{
  &quot;status&quot;: &quot;In progress&quot;,
   &quot;links&quot;: {[
    { &quot;rel&quot;:&quot;cancel&quot;, &quot;method&quot;: &quot;delete&quot;, &quot;href&quot;:&quot;/api/status/12345&quot; } ,
    { &quot;rel&quot;:&quot;edit&quot;, &quot;method&quot;: &quot;put&quot;, &quot;href&quot;:&quot;/api/status/12345&quot; }
  ]}
}
</code></pre>

<h2 id="toc_16">四、参考链接</h2>

<p><a href="https://blog.florimondmanca.com/restful-api-design-13-best-practices-to-make-your-users-happy">RESTful API Design: 13 Best Practices to Make Your Users Happy</a>, by Florimond Manca<br/>
<a href="https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design">API design</a>, by MicroSoft Azure</p>


		</div>

		

	</article>
 
	<article>
		 <header>
		  	<h1 class="entry-title"><a href="15408695578947.html">一篇文章搞定 Centos7 安装与配置JDK8</a></h1>
			<p class="meta"><time datetime="2018-10-30T11:19:17+08:00" 
			pubdate data-updated="true">2018/10/30</time></p>
		 </header>
	  	<div class="entry-content">
		  	
		  	<ul>
<li>
<a href="#toc_0">检查是否安装过JDK</a>
</li>
<li>
<a href="#toc_1">下载安装包并上传</a>
</li>
<li>
<a href="#toc_2">使用rpm的方式安装JDK</a>
</li>
<li>
<a href="#toc_3">安装完成后的检查</a>
</li>
<li>
<a href="#toc_4">配置环境变量</a>
</li>
<li>
<a href="#toc_5">安装结束</a>
</li>
</ul>


<h2 id="toc_0">检查是否安装过JDK</h2>

<pre><code class="language-shell">rpm -qa | grep java
</code></pre>

<h2 id="toc_1">下载安装包并上传</h2>

<p>注意, 这里一定选择在官网下载, 并且选择下载rpm包如图<br/>
<img src="media/15408695578947/15408696761847.jpg" alt="" style="width:562px;"/><br/>
下载好后, 上传到服务器</p>

<h2 id="toc_2">使用rpm的方式安装JDK</h2>

<pre><code class="language-shell">rpm -ivh jdk-8u191-linux-x64.rpm
</code></pre>

<h2 id="toc_3">安装完成后的检查</h2>

<p>通过上一步骤, 我们已经安装好了java, 我们可以使用如下命令检查安装结果</p>

<pre><code class="language-shell">java -version
</code></pre>

<h2 id="toc_4">配置环境变量</h2>

<pre><code class="language-shell">vim /etc/profile

JAVA_HOME=/usr/java/jdk1.8.0_191-amd64
JRE_HOME=/usr/java/jdk1.8.0_191-amd64/jre
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export JAVA_HOME JRE_HOME PATH CLASSPATH
</code></pre>

<h2 id="toc_5">安装结束</h2>

<p>至此安装结束, 需要注意的是, 在最后你可能需要重启shell, 或者source shell 配置文件来使环境变量配置生效, 具体如下:</p>

<pre><code class="language-shell">source /etc/profile
</code></pre>


		</div>

		

	</article>
 
	<article>
		 <header>
		  	<h1 class="entry-title"><a href="15402950858118.html">Nginx的启动、停止与重启</a></h1>
			<p class="meta"><time datetime="2018-10-23T19:44:45+08:00" 
			pubdate data-updated="true">2018/10/23</time></p>
		 </header>
	  	<div class="entry-content">
		  	
		  	<ul>
<li>
<a href="#toc_0">启动</a>
</li>
<li>
<a href="#toc_1">停止</a>
<ul>
<li>
<a href="#toc_2">从容停止</a>
</li>
<li>
<a href="#toc_3">快速停止</a>
</li>
<li>
<a href="#toc_4">强制停止</a>
</li>
</ul>
</li>
<li>
<a href="#toc_5">重启</a>
</li>
</ul>


<h2 id="toc_0">启动</h2>

<p>启动代码格式：nginx安装目录地址 -c nginx配置文件地址</p>

<p>例如：</p>

<pre><code class="language-shell">[root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
</code></pre>

<h2 id="toc_1">停止</h2>

<p>nginx的停止有三种方式：</p>

<h3 id="toc_2">从容停止</h3>

<p>　　1、查看进程号</p>

<pre><code class="language-shell">[root@LinuxServer ~]# ps -ef|grep nginx
</code></pre>

<p><img src="media/15402950858118/15402954030895.jpg" alt=""/></p>

<p>　　2、杀死进程</p>

<pre><code class="language-shell">[root@LinuxServer ~]# kill -QUIT 2072
</code></pre>

<p><img src="media/15402950858118/15402954134920.jpg" alt=""/></p>

<h3 id="toc_3">快速停止</h3>

<p>1、查看进程号</p>

<pre><code class="language-shell">[root@LinuxServer ~]# ps -ef|grep nginx
</code></pre>

<p><img src="media/15402950858118/15402954229262.jpg" alt=""/></p>

<p>2、杀死进程</p>

<pre><code class="language-shell">[root@LinuxServer ~]# kill -TERM 2132
</code></pre>

<p>或 </p>

<pre><code class="language-shell">[root@LinuxServer ~]# kill -INT 2132
</code></pre>

<p><img src="media/15402950858118/15402954314580.jpg" alt=""/></p>

<h3 id="toc_4">强制停止</h3>

<pre><code class="language-shell">[root@LinuxServer ~]# pkill -9 nginx
</code></pre>

<h2 id="toc_5">重启</h2>

<ul>
<li>验证nginx配置文件是否正确</li>
</ul>

<p>方法一：进入nginx安装目录sbin下，输入命令</p>

<pre><code class="language-shell">./nginx -t
</code></pre>

<p>看到如下显示</p>

<pre><code class="language-shell">nginx.conf syntax is ok

nginx.conf test is successful
</code></pre>

<p>说明配置文件正确！</p>

<p><img src="media/15402950858118/15402954436521.jpg" alt=""/></p>

<p>方法二：在启动命令-c前加-t<br/>
<img src="media/15402950858118/15402954542875.jpg" alt=""/></p>

<ul>
<li><p>重启Nginx服务<br/>
方法一：进入nginx可执行目录sbin下，输入命令</p>
<pre><code class="language-shell">./nginx -s reload
</code></pre>
<p>即可<br/>
<img src="media/15402950858118/15402954645283.jpg" alt=""/></p></li>
</ul>

<p>方法二：查找当前nginx进程号，然后输入命令：</p>

<pre><code class="language-shell">kill -HUP 进程号 
</code></pre>

<p>实现重启nginx服务<br/>
<img src="media/15402950858118/15402954740748.jpg" alt=""/></p>


		</div>

		

	</article>
 
	<article>
		 <header>
		  	<h1 class="entry-title"><a href="15391742760274.html">XRebel 使用详解</a></h1>
			<p class="meta"><time datetime="2018-10-10T20:24:36+08:00" 
			pubdate data-updated="true">2018/10/10</time></p>
		 </header>
	  	<div class="entry-content">
		  	
		  	<ul>
<li>
<a href="#toc_0">前言</a>
<ul>
<li>
<a href="#toc_1">什么是XRebel</a>
</li>
<li>
<a href="#toc_2">如何下载XRebel</a>
</li>
<li>
<a href="#toc_3">如何安装XRebel</a>
</li>
<li>
<a href="#toc_4">如何使用</a>
</li>
</ul>
</li>
<li>
<a href="#toc_5">结语</a>
</li>
</ul>


<h2 id="toc_0">前言</h2>

<p>你有没有遇到过项目打开, 一直转圈的情况, 有没有遇到过追究责任前后端开发相互扯皮, 推卸责任的情况, 有没有遇到过项目性能不理想, 却手足无措的情况, 那么XRebel正是你需要的好东西.</p>

<h3 id="toc_1">什么是XRebel</h3>

<p>XRebel 是不间断运行在 web 应用的交互式分析器，当发现问题会在浏览器中显示警告信息。XRebel 会实时监测应用代码的性能指标和可能会发生的问题。</p>

<h3 id="toc_2">如何下载XRebel</h3>

<p>地址: <a href="http://zeroturnaround.com/software/xrebel/download/">http://zeroturnaround.com/software/xrebel/download/</a></p>

<h3 id="toc_3">如何安装XRebel</h3>

<p>只需要解压下载到本地的zip压缩文件即可, 解压后的文件夹内容如图:<br/>
<img src="media/15391742760274/15391749868448.jpg" alt=""/><br/>
注意其中的xrebel.jar<br/>
真正带来魔法的, 就是这个xrebel.jar文件</p>

<h3 id="toc_4">如何使用</h3>

<p>XRebel的使用, 使用的是java代理的方式, 实际是JVM代理, 只需要添加JVM参数即可, 这意味着, 不论你是什么样的java项目, 基于servlet+jsp的web应用也好, 还是jar包(例如: spring-boot项目)项目也好, 我们都是可以使用XRebel进行性能分析和问题监控的.</p>

<p>那么接下来我们以 IDEA + Spring-boot 项目为例, 来演示如何使用.</p>

<ul>
<li><p>首先配置一个Run-configuration:<br/>
<img src="media/15391742760274/15391752470216.jpg" alt=""/></p></li>
<li><p>然后在VM options: 中添加如下内容:<br/>
-javaagent:/Users/lucas/Java-lib/maven/xrebel/xrebel.jar<br/>
我们可以清楚的看到, 使用的是JVM代理, 后边要清楚的指明之前解压出来的xrebel.jar的位置.<br/>
如图:<br/>
<img src="media/15391742760274/15391753777547.jpg" alt=""/></p></li>
<li><p>随后我们运行起来项目, 只需要点击IDEA右上角的运行图标即可</p></li>
<li><p>在上一步骤的启动日志中, 可以看到XRebel UI的访问地址:<br/>
<img src="media/15391742760274/15391757236003.jpg" alt=""/><br/>
即: <a href="http://18.18.18.112:8080/xrebel">http://18.18.18.112:8080/xrebel</a></p></li>
<li><p>这时我们访问一个开启的服务的http服务接口, 这里以postman为例:<br/>
<img src="media/15391742760274/15391756059044.jpg" alt=""/></p></li>
<li><p>这时我们就可以在XRebel UI的页面, 看到详细的接口分析内容了:<br/>
<img src="media/15391742760274/15391758462364.jpg" alt=""/><br/>
可以看到里面详细的列出的请求执行的堆栈信息, 以及每一步的执行时间, 还有每个sql的执行时间.<br/>
通过这些信息足够我们做性能分析了.</p></li>
<li><p>尤其是sql语句的完整输出, 以及执行时间的详细信息, 能给我们关注这个性能点, 带来很大的方便:<br/>
<img src="media/15391742760274/15391760173058.jpg" alt=""/></p></li>
</ul>

<h2 id="toc_5">结语</h2>

<p>以上就是本次分享的内容, 是不是已经迫不及待想要尝试一把了~</p>


		</div>

		

	</article>
  
	<div class="pagination">
	
<a href="archives.html">Blog Archives</a>
	 
	    
	</div>
</div>
 <aside class="sidebar"> 

	<section>
	  <h1>Categories</h1>
	  <ul id="recent_posts">
	  
	      <li class="post">
	        <a href="version-control.html"><strong>version-control&nbsp;(2)</strong></a>
	        
	        
	        
	      </li>
	  
	      <li class="post">
	        <a href="shell.html"><strong>shell&nbsp;(1)</strong></a>
	        
	        
	        
	      </li>
	  
	      <li class="post">
	        <a href="back-end.html"><strong>back-end&nbsp;(4)</strong></a>
	        
	        
	        
	      </li>
	  
	      <li class="post">
	        <a href="front-end.html"><strong>front-end&nbsp;(5)</strong></a>
	        
	        
	        
	      </li>
	  
	      <li class="post">
	        <a href="version-control-1.html"><strong>version-control&nbsp;(1)</strong></a>
	        
	        
	        
	      </li>
	  
	      <li class="post">
	        <a href="other.html"><strong>other&nbsp;(2)</strong></a>
	        
	        
	        
	      </li>
	   
	  </ul>
	</section>
	<section>
	  <h1>Recent Posts</h1>
	  <ul id="recent_posts">
	  
	      
		      <li class="post">
		        <a href="15413898294420.html">RESTful API 最佳实践</a>
		      </li>
	     
	  
	      
		      <li class="post">
		        <a href="15411425055347.html">LZH-DEV-GROUP Git Workflow 实践详解</a>
		      </li>
	     
	  
	      
		      <li class="post">
		        <a href="15410718240579.html">如何使用PM2进程管理器, 守护java进程</a>
		      </li>
	     
	  
	      
		      <li class="post">
		        <a href="15408811446857.html">一篇文章搞定 centos7 上的 mysql 安装</a>
		      </li>
	     
	  
	      
		      <li class="post">
		        <a href="15408703788547.html">一篇文章搞定 centos7 下安装 nvm和node</a>
		      </li>
	     
	  
	      
	  
	      
	  
	      
	  
	      
	  
	      
	  
	      
	  
	      
	  
	      
	  
	      
	  
	      
	   
	  </ul>
	</section>
	
</aside> </div></div>
  <footer role="contentinfo"><p>
  Copyright &copy; 2014 -  -
  <span class="credit">Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a> &nbsp;&nbsp; Theme by <a href="http://octopress.org">Octopress</a></span>
</p>

</footer>

  
    




</body>
</html>